package com.element.oauth2.server.handler;

import com.alibaba.fastjson.JSON;
import com.common.core.exception.code.SecurityErrorCode;
import com.common.core.results.VoidResult;
import com.element.oauth2.constant.SecurityParams;
import com.element.oauth2.utils.ResponseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenIntrospection;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenIntrospectionAuthenticationToken;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class TokenIntrospectionSuccessHandler implements AuthenticationSuccessHandler {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        logger.info("TokenIntrospectionSuccessHandler校验成功");
        if (authentication instanceof OAuth2TokenIntrospectionAuthenticationToken) {
            OAuth2TokenIntrospectionAuthenticationToken authenticationToken = (OAuth2TokenIntrospectionAuthenticationToken) authentication;
            OAuth2TokenIntrospection introspection = authenticationToken.getTokenClaims();
            if (null != introspection) {
                Map<String, Object> claimMap = introspection.getClaims();
                if (!CollectionUtils.isEmpty(claimMap)) {
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("active", claimMap.get("active"));
                    resultMap.put(SecurityParams.CLIENT_ID, claimMap.get("client_id"));
                    Instant endTime = (Instant) claimMap.get("exp");
                    resultMap.put("expires_in", getExpiresIn(endTime));
                    ResponseUtil.writeJson(response, JSON.toJSONString(resultMap));
                    return;
                }
            }
        }
        ResponseUtil.writeJson(response, VoidResult.failed(SecurityErrorCode.A_INTERNAL_AUTHENTICATION_SERVICE_EXCEPTION));
    }

    public String getExpiresIn(Instant instant) {
        if (null == instant) {
            return "0";
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(new Date(instant.getEpochSecond() * 1000));
    }
}